package com.candy.candyuser.model.service.impl;

import com.candy.candycommon.utils.ResultBean;
import com.candy.candyproductservice.dto.ProductDTO;
import com.candy.candyproductservice.service.ProductService;
import com.candy.candyuser.model.service.UserManager;
import com.candy.candyuser.model.service.UserService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

/**
 * @author suYanLong
 * @version 1.0
 * @date 2023/4/19 16:40
 * @Description 描述
 */
@Slf4j
@Service
@AllArgsConstructor
public class UserManagerImpl implements UserManager {

    private final UserService userService;

    private final ProductService productService;

    /**
     * TCC配置RM和seata配置方式一样
     * TODO 注意[TCC模式]
     *  1、必须使用@GlobalTransactional开启事务
     *  2、被调用接口接口类上使用@LocalTCC标注，try方法上使用@TwoPhaseBusinessAction(name = "addUserTcc", commitMethod = "addUserTccCommit", rollbackMethod = "addUserTccRollback", useTCCFence = true)标注
     *  name全局唯一，commitMethod及commit执行方法，rollbackMethod及cancel执行方法，useTCCFence（默认false）设置为true，seata1.5.1的新特性，用于解决TCC幂等，悬挂，空回滚问题，需增加日志表tcc_fence_log
     *  BusinessActionContextParameter注解 传递参数到二阶段中
     *  3、实现类try方法中需要使用本地事务@Transactional保证提交
     *
     * @return
     * @BusinessActionContextParameter(paramName = "orderId") Long orderId
     */
    @Override
    @GlobalTransactional(name = "managerAddUser", rollbackFor = Exception.class)
    public ResultBean managerAddUser() {
        userService.addUserTcc();
        ProductDTO productDTO = new ProductDTO();
        productDTO.setId(1l);
        productDTO.setSubNum(1);
        ResultBean resultBean = productService.subProduct(productDTO);
        log.info("扣减库存结果：{}", resultBean);
        return ResultBean.ok();
    }

}
